package com.cloud.service.coupon.impl;

import com.cloud.bean.coupon.BatchCoupon;
import com.cloud.bean.coupon.CouponRule;
import com.cloud.common.BaseReturn;
import com.cloud.common.CouponStatus;
import com.cloud.controller.coupon.FormBatchCoupon;
import com.cloud.mapper.coupon.BatchCouponMapper;
import com.cloud.service.coupon.BatchCouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.service.coupon.CouponRuleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.cloud.common.ArraysUtils.getC;
import static com.cloud.common.OrderUtils.getUppercaseLetter;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liuyuan
 * @since 2022-08-06
 */
@Service
public class BatchCouponServiceImpl extends ServiceImpl<BatchCouponMapper, BatchCoupon> implements BatchCouponService {
    @Autowired
    CouponRuleService couponRuleService;
    @Autowired
    BatchCouponService batchCouponService;
    @Autowired
    BatchCouponMapper batchCouponMapper;


    //事物回滚需要处理
    @Override
    public boolean create(FormBatchCoupon formBatchCoupon) {
        BatchCoupon batchCoupon = buildBatchCoupon(formBatchCoupon);
        //int batchCouponId = saveBatch();
        boolean result = batchCouponService.save(batchCoupon);
        if(!result){
            return false;
        }
        Long[] rules = formBatchCoupon.getRules();
        //判断规则如果数组长度大于0 说明是有规则的需要创建联表
        if( rules.length >0){
            for (Long id: rules) {
                boolean save = saveCouponRule(formBatchCoupon, id);
                //创建的过程中如果有一条创建失败了就直接停止
                if(!save) {
                   return false;
                }
            }
        }else {
            return true;
        }
       return true;
    }

    @Override
    @Transactional()
    public BaseReturn updateRules(FormBatchCoupon formBatchCoupon) {
        //对批次信息的修改
        int i = batchCouponMapper.updateById(formBatchCoupon);
        if(i!=1){
            return  BaseReturn.build("5000","修改总表失败");
        }
        //1.formBatchId 目前没有进行操作的原有的规则
        List<CouponRule> couponRules = couponRuleService.listByBatchCouponId(formBatchCoupon.getId());
        if(couponRules.size() > 0 ){
            Long[] rules = formBatchCoupon.getRules();
            if(rules.length > 0){
                List<Long> longs = Arrays.asList(rules);
                for (Long ruleId:longs) {
                    //那到传来的规则一定是有 查询没有进行操作的原有的规则 如果存在就不添加 不存就添加
                    CouponRule byIdAndRuleId = couponRuleService.getByIdAndRuleId(formBatchCoupon.getId(), ruleId);
                    //不存在就添加
                    if(byIdAndRuleId == null){
                        boolean b = saveCouponRule(formBatchCoupon, ruleId);
                        if(!b){
                            return BaseReturn.build("5000","创建规则失败请你查询数据库数据");
                        }
                    }
                }
                //添加过的规则 包含传来的规则和原有的规则
                List<CouponRule> nowCouponRules = couponRuleService.listByBatchCouponId(formBatchCoupon.getId());
                //取两个数组的差集
                List<Long> oldRules = new ArrayList<>();
                for (CouponRule couponRule: nowCouponRules) {
                    oldRules.add(couponRule.getRuleId());
                }
                Long[] oldRuleList = oldRules.toArray(new Long[0]);
                Long[] delRuleList = getC(oldRuleList, rules);
                //传来的规则一定要有 除了传来的数据其他的规则一律删除
                for (Long delId: delRuleList) {
                    boolean b = couponRuleService.delByRuleIdAndBatchCouponId(delId, formBatchCoupon.getId());
                    if(!b){
                        return BaseReturn.build("5000","删除规则失败请你查询数据库数据");
                    }
                }
            }else {
                //没有传规则 删除原有的规则
               int num  = couponRuleService.delByBatchCouponId(formBatchCoupon.getId());
               if(num < 1){
                   return BaseReturn.build("5000","删除规则失败，请联系管理员");
               }
            }
        }else {
            Long[] rules = formBatchCoupon.getRules();
            if(rules.length > 0){
                List<Long> longs = Arrays.asList(rules);
                for (Long ruleId: longs) {
                    boolean b = saveCouponRule(formBatchCoupon, ruleId);
                    if(!b){
                        return BaseReturn.build("5000","创建规则失败请你查询数据库数据");
                    }
                }
            }
        }
        //2.那传来的规则id 和 formBatchId 也去查 查规则表 如果查不到就创建。
        //3.那传来的规则id 和 formBatchId 也去查  查到的规则 和查出全部的规则 对比 如果有就保留 如果没有就删除

        return BaseReturn.build("2000","修改成功");
    }

    /**
     * 1.根据id把这个批次优惠券查询出来
     * 2.如果没有这个批次优惠卷 要返回错误信息
     * 3.有的话就修改响应状态
     * */
    @Override
    public BaseReturn push(Long id) {
        BatchCoupon batchCoupon = batchCouponMapper.selectById(id);
        if(batchCoupon == null){
            return BaseReturn.build("5000","没有这个批次优惠卷");
        }
        batchCoupon.setStatus(CouponStatus.PUSH.name());
        int i = batchCouponMapper.updateById(batchCoupon);
        if(i !=1){
            return BaseReturn.build("5000","发行失败");
        }
        return BaseReturn.build("2000","发行成功");
    }

    private  boolean saveCouponRule(FormBatchCoupon formBatchCoupon,Long id){
        CouponRule couponRule = new CouponRule();
        couponRule.setIsValid(1);
        couponRule.setBatchCouponId(formBatchCoupon.getId());
        couponRule.setBatchCode(formBatchCoupon.getBatchCode());
        couponRule.setRuleId(id);
        couponRule.setOperatorId(formBatchCoupon.getOperatorId().intValue());
        couponRule.setCustomerOn(formBatchCoupon.getCustomerOn());
        return couponRuleService.save(couponRule);
    }

    private BatchCoupon buildBatchCoupon(FormBatchCoupon formBatchCoupon) {
        BatchCoupon batchCoupon = new BatchCoupon();
        BeanUtils.copyProperties(formBatchCoupon,batchCoupon);
        String uppercaseLetter = getUppercaseLetter(15);
        batchCoupon.setBatchCode(uppercaseLetter);
       //batchCoupon.setType("DAYGODCOUPON");
        batchCoupon.setStatus(CouponStatus.CREATE.name());

        return batchCoupon;
    }
}
